# coding:utf-8

import os
import json
import datetime
import urllib
from functools import wraps

from flask import (
    render_template, redirect, request, url_for, flash, current_app
)
from flask_login import (
    login_user, logout_user, login_required, current_user
)

from common.constant import (
    USE_SMS_BID_WIN_NOTIFY, OUTBOUND_USE_VIRTUAL_NUMBER, BID_USER_LIMIT,
    WATERING_INDEX, MAINTAIN_USER_LIMIT, Captcha_Sms_Channel_Key,
    SECOND_WATERING_INDEX, OTHER_WATERING_INDEX)
from app.utils import ApiResponse
from . import auth_bp
from .. import db
from ..models import get_timestamp
from .models import AdminUser
from .constant import (
    AgentState, TO_RATE_CACHE_KEY, PROTOCOL_VERSION_KEY,
    CaptchaSmsChannel, TODAY_DEMAND_COUNT)
from .forms import (
    LoginForm, ChangePasswordForm, AdminUserForm, ConfForm, AppVersionForm
)


def administrator_required(func):
    """
    判断是否系统管理员装饰器
    """
    @wraps(func)
    def decorated_view(*args, **kwargs):
        if not current_user.is_administrator:
            flash('您无权访问该页面')
            return redirect(url_for('main_bp.index'))
        return func(*args, **kwargs)
    return decorated_view


@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        admin_user = AdminUser.query.filter_by(
            username=form.username.data).first()
        if admin_user is not None \
            and admin_user.verify_pwd(form.password.data) \
            and admin_user.deleted_at == 0:
            admin_user.upgrade_session_token()
            login_user(admin_user, form.remember_me.data)
            return redirect(request.args.get('next') or url_for('main_bp.index'))
        flash('无效的用户名或密码.')
    return render_template('login.html', form=form)


@auth_bp.route('/seven_moor', methods=['GET', 'POST'])
def seven_moor():
    return render_template('seven_moor.html')


@auth_bp.route('/logout')
@login_required
def logout():
    logout_user()
    flash('成功退出.')
    return redirect(url_for('main_bp.index'))


@auth_bp.route('/change-password', methods=['GET', 'POST'])
@login_required
def change_password():
    form = ChangePasswordForm()
    if form.validate_on_submit():
        if current_user.verify_pwd(form.old_password.data):
            current_user.pwd = form.password.data
            db.session.add(current_user)
            flash('密码已更新.')
            current_user.upgrade_session_token()
            return redirect(url_for('main_bp.index'))
        else:
            flash('无效的密码.')
    return render_template("change_password.html", form=form)


@auth_bp.route('/admin_user_list')
@login_required
@administrator_required
def admin_user_list():
    page = request.args.get('page', 1, type=int)
    pagination = AdminUser.query.order_by(AdminUser.id.asc()).paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    admin_users = pagination.items
    return render_template(
        'admin_user_list.html',
        admin_users=admin_users,
        pagination=pagination,
        page=page,
    )


@auth_bp.route('/add_admin_user', methods=['GET', 'POST'])
@login_required
@administrator_required
def add_admin_user():
    form = AdminUserForm()
    if form.validate_on_submit():

        if form.username.data:
            tmp_admin_user = AdminUser.query.filter_by(
                username=form.username.data).first()
            if tmp_admin_user:
                flash('该账号已被使用，请设置另外的账号')
                return render_template('admin_user_add.html', form=form)

        if form.seven_moor_account.data:
            tmp_admin_user = AdminUser.query.filter_by(
                seven_moor_account=form.seven_moor_account.data).first()
            if tmp_admin_user:
                flash('该七陌座席已被使用，请设置另外的账号')
                return render_template('admin_user_add.html', form=form)

        admin_user = AdminUser()
        form.populate_obj(admin_user)
        admin_user.pwd = form.new_pwd.data
        db.session.add(admin_user)
        flash('新增管理员成功')
        return redirect(url_for('auth_bp.admin_user_list'))
    return render_template('admin_user_add.html', form=form)


@auth_bp.route('/edit_admin_user/<int:admin_user_id>', methods=['GET', 'POST'])
@login_required
@administrator_required
def edit_admin_user(admin_user_id):
    admin_user = AdminUser.query.get_or_404(admin_user_id)
    form = AdminUserForm()

    if form.validate_on_submit():
        if form.username.data:
            tmp_admin_user = AdminUser.query.filter_by(
                username=form.username.data).first()
            if tmp_admin_user and tmp_admin_user.id != admin_user.id:
                flash('该账号已被使用，请设置另外的账号')
                return render_template('admin_user_edit.html', form=form)

        if form.seven_moor_account.data:
            tmp_admin_user = AdminUser.query.filter_by(
                seven_moor_account=form.seven_moor_account.data).first()
            if tmp_admin_user and tmp_admin_user.id != admin_user.id:
                flash('该七陌座席已被使用，请设置另外的账号')
                return render_template('admin_user_edit.html', form=form)

        form.populate_obj(admin_user)
        if form.new_pwd.data:
            admin_user.pwd = form.new_pwd.data

        # add by zhouhl 2018-01-02
        if form.is_deleted.data:
            admin_user.deleted_at = get_timestamp()
        else:
            admin_user.deleted_at = 0

        flash('修改成功')
        return redirect(url_for('auth_bp.admin_user_list'))

    form = AdminUserForm(obj=admin_user)
    if admin_user.deleted_at:
        form.is_deleted.data = True

    return render_template('admin_user_edit.html', form=form)


@auth_bp.route('/agent/login', methods=['GET'])
def agent_login():
    current_user.agent_state = AgentState.LOGIN.value
    current_user.agent_login_time = datetime.datetime.now()
    return ApiResponse()


@auth_bp.route('/agent/logout', methods=['GET'])
def agent_logout():
    current_user.agent_state = AgentState.LOGOUT.value
    return ApiResponse()


@auth_bp.route('/conf/set', methods=['GET', 'POST'])
def conf_set():
    """
    created by chenhj at 2017/8/31
    配置相关设置项
    """
    form = ConfForm()
    if form.validate_on_submit():
        rate_to_set = form.to_rate.data
        current_app.redis.set(TO_RATE_CACHE_KEY, rate_to_set)
        protocol_version_to_set = form.protocol_version.data
        current_app.redis.set(PROTOCOL_VERSION_KEY, protocol_version_to_set)
        use_sms_win_notify_to_set = form.use_sms_win_bid_notify.data
        current_app.redis.set(USE_SMS_BID_WIN_NOTIFY, json.dumps(use_sms_win_notify_to_set))
        outbound_use_virtual_number = form.outbound_use_virtual_number.data
        current_app.redis.set(OUTBOUND_USE_VIRTUAL_NUMBER, json.dumps(outbound_use_virtual_number))
        current_app.redis.set(BID_USER_LIMIT, form.bid_user_limit.data)
        current_app.redis.set(MAINTAIN_USER_LIMIT, form.maintain_user_limit.data)
        watering_index = form.watering_index.data
        current_app.redis.set(WATERING_INDEX, watering_index)

        second_watering_index = form.second_watering_index.data
        current_app.redis.set(SECOND_WATERING_INDEX, second_watering_index)

        other_watering_index = form.other_watering_index.data
        current_app.redis.set(OTHER_WATERING_INDEX, other_watering_index)

        captcha_sms_channel = form.captcha_sms_channel.data
        current_app.redis.set(Captcha_Sms_Channel_Key, captcha_sms_channel)

        today_demand_count = form.today_demand_count.data
        current_app.redis.set(TODAY_DEMAND_COUNT, today_demand_count)
        flash('修改成功')
    else:
        to_rate = current_app.redis.get(TO_RATE_CACHE_KEY) or '0'
        protocol_version = current_app.redis.get(PROTOCOL_VERSION_KEY) or ''
        use_sms_win_bid_notify = json.loads(current_app.redis.get(USE_SMS_BID_WIN_NOTIFY) or 'false')
        outbound_use_virtual_number = json.loads(current_app.redis.get(OUTBOUND_USE_VIRTUAL_NUMBER) or 'false')
        bid_user_limit = current_app.redis.get(BID_USER_LIMIT) or '1'
        maintain_user_limit = current_app.redis.get(MAINTAIN_USER_LIMIT) or '1'
        watering_index = current_app.redis.get(WATERING_INDEX) or '1.0'
        second_watering_index = current_app.redis.get(SECOND_WATERING_INDEX) or '1.0'
        other_watering_index = current_app.redis.get(OTHER_WATERING_INDEX) or '1.0'
        captcha_sms_channel = current_app.redis.get(Captcha_Sms_Channel_Key) or CaptchaSmsChannel.MENG_WANG.value

        today_demand_count = current_app.redis.get(TODAY_DEMAND_COUNT) or '1.0'

        form.to_rate.data = to_rate
        form.protocol_version.data = protocol_version
        form.use_sms_win_bid_notify.data = use_sms_win_bid_notify
        form.outbound_use_virtual_number.data = outbound_use_virtual_number
        form.bid_user_limit.data = bid_user_limit
        form.maintain_user_limit.data = maintain_user_limit
        form.watering_index.data = watering_index
        form.second_watering_index.data = second_watering_index
        form.other_watering_index.data = other_watering_index
        form.captcha_sms_channel.data = captcha_sms_channel
        form.today_demand_count.data = today_demand_count

    return render_template('conf_set.html', form=form)


@auth_bp.route('/app/version', methods=['GET', 'POST'])
def app_version():
    """
    created by chenhj at 2018/5/8

    url暂时都直接写死
    """
    from app.api_v2.constant import CURRENT_APP_VERSION_KEY

    android = 'android'
    ios = 'ios'

    form = AppVersionForm()
    if form.validate_on_submit():
        current_app.redis.hmset(
            CURRENT_APP_VERSION_KEY % android, {
                'version': form.android_version.data,
                'url': urllib.parse.urljoin(
                    os.environ.get('opc_host'), 'api_v2/wanpinghui.apk'
                ),
            }
        )
        current_app.redis.hmset(
            CURRENT_APP_VERSION_KEY % ios, {
                'version': form.ios_version.data,
                'url': 'https://itunes.apple.com/cn/app/%E4%B8%87%E5%B1%8F%E6%B1%87/id1337664276?mt=8'
            }
        )

        if form.android_file.data:
            basedir = os.path.join(
                os.path.abspath(os.path.dirname(__file__)), '../../download_app'
            )
            filename = 'wanpinghui.apk'
            form.android_file.data.save(os.path.join(basedir, filename))

        flash('保存成功')
    else:
        android_version = current_app.redis.hgetall(
            CURRENT_APP_VERSION_KEY % android
        ) or dict()
        form.android_version.data = android_version.get('version')

        ios_version = current_app.redis.hgetall(
            CURRENT_APP_VERSION_KEY % ios
        ) or dict()
        form.ios_version.data = ios_version.get('version')

    return render_template('app_version.html', form=form)
